﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bluyel.Core
{
    /// <summary>
    /// Data builder manager.
    /// Manage creation of all data (not type or instruction).
    /// </summary>
    public class DataBuilder
    {
        FactoryMgrBase _factoryMgr;

        TypeMgrBase _typeMgr;

        ListDataMgr _listDataMgr;

        TypeFinderBase _typeFinder;

        //=====================================================================
        #region Constructor.

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="factory"></param>
        public DataBuilder(FactoryMgrBase factoryMgr, TypeMgrBase typeMgr, TypeFinderBase typeFinder, ListDataMgr listDataNamedMgr)
        {
            _factoryMgr = factoryMgr;
            _typeMgr = typeMgr;
            //_typePhyMgr = typePhysQtyMgr;

            _typeFinder = typeFinder;
            _listDataMgr = listDataNamedMgr;
        }
        #endregion

        //=====================================================================
        #region Public Create DVal type basic methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a (empty) data value, set the type.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public IValue CreateDVal(ITypeBasic type)
        {
            return _factoryMgr.FactoryValue.CreateValue(type);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create an int data value.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public ValueInt CreateDValInt(int val)
        {
            // check that the type int exists
            if (_typeFinder.GetTypeInt() == null)
                return null;

            return _factoryMgr.FactoryValue.CreateValueInt(val);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a double data value.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public ValueDouble CreateDValDouble(double val)
        {
            // check that the type double exists
            if (_typeFinder.GetTypeDouble() == null)
                return null;

            return _factoryMgr.FactoryValue.CreateValueDouble(val);
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// Create a string data value.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public ValueString CreateDValString(string val)
        {
            // check that the type string exists
            if (_typeFinder.GetTypeString() == null)
                return null;

            // ok the type string is defined
            return _factoryMgr.FactoryValue.CreateValueString(val);
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// Create a bool data value.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public ValueBool CreateDValBool(bool val)
        {
            // check that the type bool exists
            if (_typeFinder.GetTypeBool() == null)
                return null;

            return _factoryMgr.FactoryValue.CreateValueBool(val);
        }

        #endregion


        //=====================================================================
        #region Public Set DVal methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Set a DV to a data named (var or const).
        /// </summary>
        /// <param name="data"></param>
        /// <param name="dataValue"></param>
        /// <returns></returns>
        public bool SetDVal(IDBasic data, IValueBasic dataValue)
        {
            if (data == null || dataValue == null)
                return false;
            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;

            // check that the Data type is same as the the type of the data value
            if (!_typeFinder.AreSameType(data, dataValue))
                return false;

            // set the DV
            data.SetDVal(dataValue);
            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Set an int value to a DVal Int.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public bool SetVal(DInt data, int val)
        {
            if (data == null)
                return false;

            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;

            ValueInt dv = CreateDValInt(val);

            // set the DV
            data.SetDVal(dv);
            return true;
        }

        //---------------------------------------------------------------------
        public bool SetVal(DDouble data, double val)
        {
            if (data == null)
                return false;
            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;

            ValueDouble dv = CreateDValDouble(val);

            // set the DV
            data.SetDVal(dv);
            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Set a value to data named type string.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public bool SetVal(DString data, string val)
        {
            if (data == null)
                return false;
            if (val == null)
                return false;
            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;

            ValueString dv = CreateDValString(val);

            // set the DV
            data.SetDVal(dv);
            return true;
        }

        //---------------------------------------------------------------------
        public bool SetVal(DBool data, bool val)
        {
            if (data == null)
                return false;
            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;

            ValueBool dv = CreateDValBool(val);

            // set the DV
            data.SetDVal(dv);
            return true;
        }

        #endregion

        //=====================================================================
        #region Public Create Var & Const (DataNamed) type basic methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type basic.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public IDBasic CreateVarBasic(string name, ITypeBasic type)
        {
            return CreateDBasic(name, type, VarOrConst.Var);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a const data (dataNamed), type basic.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public IDBasic CreateConstBasic(string name, ITypeBasic type)
        {
            return CreateDBasic(name, type, VarOrConst.Const);
        }


        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type int (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DInt CreateVarInt(string name, int val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;

            ITypeBasic type = _typeFinder.GetTypeInt();

            DInt dInt = _factoryMgr.FactoryData.CreateDInt(name, type, VarOrConst.Var, val);
            SetVal(dInt, val);

            return dInt;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type int (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DInt CreateVarInt(string name)
        {
            return CreateVarInt(name, TypeDef.DefValInt);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a const (dataNamed), type int (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DInt CreateConstInt(string name, int val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;

            ITypeBasic type = _typeFinder.GetTypeInt();

            DInt dInt = _factoryMgr.FactoryData.CreateDInt(name, type, VarOrConst.Const, val);
            SetVal(dInt, val);

            return dInt;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type double (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DDouble CreateVarDouble(string name, double val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;

            ITypeBasic type = _typeFinder.GetTypeDouble();

            DDouble dDbl = _factoryMgr.FactoryData.CreateDDouble(name, type, VarOrConst.Var, val);
            SetVal(dDbl, val);

            return dDbl;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type double (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DDouble CreateVarDouble(string name)
        {
            return CreateVarDouble(name, TypeDef.DefValDouble);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a constant (dataNamed), type double (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DDouble CreateConstDouble(string name, double val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;

            ITypeBasic type = _typeFinder.GetTypeInt();

            DDouble dDouble = _factoryMgr.FactoryData.CreateDDouble(name, type, VarOrConst.Const, val);
            SetVal(dDouble, val);

            return dDouble;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type string (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DString CreateVarString(string name, string val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;
            // TODO: manage the case when string is null (nullable?)
            if (val == null)
                return null;

            ITypeBasic type = _typeFinder.GetTypeString();

            DString dString = _factoryMgr.FactoryData.CreateDString(name, type, VarOrConst.Var, val);
            SetVal(dString, val);
            return dString;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type string (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DString CreateVarString(string name)
        {
            return CreateVarString(name, TypeDef.DefValString);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a constant (dataNamed), type string (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DString CreateConstString(string name, string val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;
            // TODO: manage the case when string is null (nullable?)
            if (val == null)
                return null;

            ITypeBasic type = _typeFinder.GetTypeString();
            DString dString = _factoryMgr.FactoryData.CreateDString(name, type, VarOrConst.Const, val);
            SetVal(dString, val);
            return dString;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type bool (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DBool CreateVarBool(string name, bool val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;
            ITypeBasic type = _typeFinder.GetTypeBool();

            DBool dBool = _factoryMgr.FactoryData.CreateDBool(name, type, VarOrConst.Var, val);
            SetVal(dBool, val);
            return dBool;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a var (dataNamed), type bool (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DBool CreateVarBool(string name)
        {
            return CreateVarBool(name, TypeDef.DefValBool);
        }


        //---------------------------------------------------------------------
        /// <summary>
        /// Create a constant (dataNamed), type bool (basic type).
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public DBool CreateConstBool(string name, bool val)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;
            ITypeBasic type = _typeFinder.GetTypeBool();

            DBool dBool = _factoryMgr.FactoryData.CreateDBool(name, type, VarOrConst.Const, val);
            SetVal(dBool, val);
            return dBool;
        }
        #endregion

        //=====================================================================
        #region Public Create/AddMember DataNStruct methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a data structure.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public IDStruct CreateDStruct(string name, VarOrConst varOrConst)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;

            // get the internal DataStruct type
            ITypeStruct type= _typeFinder.GetTypeStruct();

            // not exists, so not possible to create a dat named struct
            if (type == null)
                return null;

            // ok, create the data named structure
            IDStruct dataSt = new DStruct(name, type, varOrConst);

            return dataSt;
        }

        //---------------------------------------------------------------------
        public IDStruct CreateVarStruct(string name)
        {
            return CreateDStruct(name, VarOrConst.Var);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a new data member type basic to a DataNamed structure.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="typeBasic"></param>
        /// <returns></returns>
        //public IDBasic CreateDataNamedStructMember(IDStruct ds, string name, ITypeBasic typeBasic, VarOrConst varOrConst)
        //{
        //    if (ds == null)
        //        return null;
        //    if (string.IsNullOrWhiteSpace(name))
        //        return null;
        //    if (typeBasic == null)
        //        return null;

        //    // check that the name is not already used by a existing member
        //    if (ds.FindMember(name) != null)
        //        return null;

        //    IDBasic d;
        //    // create a data basic type
        //    if(varOrConst == VarOrConst.Var)            
        //        d= CreateVarBasic(name, typeBasic);            
        //    else
        //        d = CreateConstBasic(name, typeBasic);            

        //    // add it as a member to the data named structure
        //    if (!ds.AddMember(d))
        //        return null;
        //    return d;
        //}

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a new data member type basic to a DataNamed structure.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="typeBasic"></param>
        /// <returns></returns>
        public DInt CreateDataNamedStructMemberInt(IDStruct ds, string name, VarOrConst varOrConst, int val)
        {
            if (ds == null)
                return null;
            if (string.IsNullOrWhiteSpace(name))
                return null;

            // check that the name is not already used by a existing member
            if (ds.FindMember(name) != null)
                return null;

            DInt d;
            // create a data basic type
            if (varOrConst == VarOrConst.Var)
                d = CreateVarInt(name,val);
            else
                d = CreateConstInt(name,val);

            // add it as a member to the data named structure
            if (!ds.AddMember(d))
                return null;
            return d;
        }

        //---------------------------------------------------------------------
        public DInt AddVarStructMemberInt(IDStruct ds, string name, int val)
        {
            return CreateDataNamedStructMemberInt(ds, name, VarOrConst.Var, val);
        }

        //---------------------------------------------------------------------
        public DInt AddVarStructMemberInt(IDStruct ds, string name)
        {
            return AddVarStructMemberInt(ds, name, TypeDef.DefValInt);
        }

        //---------------------------------------------------------------------
        public DInt AddConstStructMemberInt(IDStruct ds, string name, int val)
        {
            return CreateDataNamedStructMemberInt(ds, name, VarOrConst.Const, val);
        }

        //---------------------------------------------------------------------
        public DDouble AddDataNamedStructMemberDouble(IDStruct ds, string name, VarOrConst varOrConst, double val)
        {
            if (ds == null)
                return null;
            if (string.IsNullOrWhiteSpace(name))
                return null;

            // check that the name is not already used by a existing member
            if (ds.FindMember(name) != null)
                return null;

            DDouble d;
            // create a data basic type
            if (varOrConst == VarOrConst.Var)
                d = CreateVarDouble(name, val);
            else
                d = CreateConstDouble(name, val);

            // add it as a member to the data named structure
            if (!ds.AddMember(d))
                return null;
            return d;
        }

        //---------------------------------------------------------------------
        public DDouble AddVarStructMemberDouble(IDStruct ds, string name, double val)
        {
            return AddDataNamedStructMemberDouble(ds, name,VarOrConst.Var, val);
        }

        //---------------------------------------------------------------------
        public DDouble AddVarStructMemberDouble(IDStruct ds, string name)
        {
            return AddDataNamedStructMemberDouble(ds, name, VarOrConst.Var, TypeDef.DefValDouble);
        }

        //---------------------------------------------------------------------
        public DDouble AddConstStructMemberDouble(IDStruct ds, string name, double val)
        {
            return AddDataNamedStructMemberDouble(ds, name, VarOrConst.Const, val);
        }

        //---------------------------------------------------------------------
        public DString AddDataNamedStructMemberString(IDStruct ds, string name, VarOrConst varOrConst, string val)
        {
            if (ds == null)
                return null;
            if (string.IsNullOrWhiteSpace(name))
                return null;
            if (val == null)
                return null;

            // check that the name is not already used by a existing member
            if (ds.FindMember(name) != null)
                return null;

            DString d;
            // create a data basic type
            if (varOrConst == VarOrConst.Var)
                d = CreateVarString(name, val);
            else
                d = CreateConstString(name, val);

            // add it as a member to the data named structure
            if (!ds.AddMember(d))
                return null;
            return d;
        }

        //---------------------------------------------------------------------
        public DString AddVarStructMemberString(IDStruct ds, string name, string val)
        {
            return AddDataNamedStructMemberString(ds, name, VarOrConst.Var, val);
        }

        //---------------------------------------------------------------------
        public DString AddVarStructMemberString(IDStruct ds, string name)
        {
            // provide a default value
            return AddDataNamedStructMemberString(ds, name, VarOrConst.Var, TypeDef.DefValString);
        }

        //---------------------------------------------------------------------
        public DString AddConstStructMemberString(IDStruct ds, string name, string val)
        {
            return AddDataNamedStructMemberString(ds, name, VarOrConst.Const, val);
        }

        //---------------------------------------------------------------------
        public DBool AddDataNamedStructMemberBool(IDStruct ds, string name, VarOrConst varOrConst, bool val)
        {
            if (ds == null)
                return null;
            if (string.IsNullOrWhiteSpace(name))
                return null;

            // check that the name is not already used by a existing member
            if (ds.FindMember(name) != null)
                return null;

            DBool d;
            // create a data basic type
            if (varOrConst == VarOrConst.Var)
                d = CreateVarBool(name, val);
            else
                d = CreateConstBool(name, val);

            // add it as a member to the data named structure
            if (!ds.AddMember(d))
                return null;
            return d;
        }

        //---------------------------------------------------------------------
        public DBool AddVarStructMemberBool(IDStruct ds, string name)
        {
            // provide a default value
            return AddDataNamedStructMemberBool(ds, name,VarOrConst.Var, TypeDef.DefValBool);
        }

        //---------------------------------------------------------------------
        public DBool AddVarStructMemberBool(IDStruct ds, string name, bool val)
        {
            // provide a default value
            return AddDataNamedStructMemberBool(ds, name, VarOrConst.Var, val);
        }

        //---------------------------------------------------------------------
        public DBool AddConstStructMemberBool(IDStruct ds, string name, bool val)
        {
            // provide a default value
            return AddDataNamedStructMemberBool(ds, name, VarOrConst.Const, val);
        }

        //---------------------------------------------------------------------
        public IDPhyLength AddVarStructMemberPhyLength(IDStruct dataSt, string name, VarOrConst varOrConst, double val, TypePhyLengthPrefix prefix)
        {
            if (dataSt == null)
                return null;

            IDPhyLength dataPhy = CreateDPhyLength(name, varOrConst, val, prefix);
            if(dataPhy==null)
                return null;

            if (!dataSt.AddMember(dataPhy))
                return null;

            return dataPhy;
        }

        //---------------------------------------------------------------------
        public IDPhyLength AddVarStructMemberPhyLength(IDStruct dataSt, string name, double val, TypePhyLengthPrefix prefix)
        {
            return AddVarStructMemberPhyLength(dataSt, name, VarOrConst.Var, val, prefix);
        }

        //---------------------------------------------------------------------
        public IDPhyLength AddConstStructMemberPhyLength(IDStruct dataSt, string name, double val, TypePhyLengthPrefix prefix)
        {
            return AddVarStructMemberPhyLength(dataSt, name, VarOrConst.Const, val, prefix);
        }

        //---------------------------------------------------------------------
        public IDPhyLength AddVarStructMemberPhyLength(IDStruct dataSt, string name)
        {
            return AddVarStructMemberPhyLength(dataSt, name, 0, TypePhyLengthPrefix.Metre);
        }

        //---------------------------------------------------------------------
        // remove a member, by the name.
        public bool RemoveVarStructMember(IDStruct dataSt, string name)
        {
            if (dataSt == null)
                return false;
            if (string.IsNullOrWhiteSpace(name))
                return false;
            return dataSt.RemoveMember(name);
        }

        #endregion

        //=====================================================================
        #region Public Create DataNamed Enum methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a data Named typeof enum, 
        /// Set the selection mode of the data enum: The selectMode of the type must be : SetInVar,
        /// or both selectMode must be the same.
        /// 
        /// No default selected/current (null).
        /// </summary>
        /// <param name="typeEnum"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public IDEnumString CreateVarEnumString(ITypeEnumString typeEnum, DEnumSelectMode selectMode, string name)
        {
            if(typeEnum==null)
                return null;
            if (string.IsNullOrWhiteSpace(name))
                return null;

            // check the select mode, must match the select mode of the type
            if (!CheckEnumSelectMode(typeEnum, selectMode))
                return null;

            // check that the type enum is defined?
            if (!_typeFinder.ContainsTypeEnum(typeEnum))
                return null;

            // create the data enum, based on the typeLOV
            IDEnumString dataLov = new DEnumString(name, typeEnum);

            return dataLov;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a data Named typeof enum.
        /// 
        /// The default mode is: OneOf (ManyOf).
        /// 
        /// The default selected/current value if the first (or none?)
        /// </summary>
        /// <param name="typeEnum"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public IDEnumString CreateVarEnumString(ITypeEnumString typeEnum, string name)
        {
            return CreateVarEnumString(typeEnum, DEnumSelectMode.Single, name);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Set the current value of the enum, by the value (a string value).
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SelectEnumVal(IDEnumString dataEnum, string value)
        {
            if (dataEnum == null)
                return false;
            if (string.IsNullOrWhiteSpace(value))
                return false;

            // check, the value to select must be present in the type LOV
            // TODO: utile? le check est fait dans SelectValue()
            ValueString dvValue = _typeFinder.FindValueInTypeEnum(dataEnum.TypeEnum, value);
            if (dvValue == null)
                return false;

            // ok select this value
            return dataEnum.SelectVal(dvValue);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// return true is the enum contains the item.
        /// Check in the type enum.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool IsEnumContainsVal(IDEnumString dataEnum, string value)
        {
            if (dataEnum == null)
                return false;
            if (string.IsNullOrWhiteSpace(value))
                return false;

            // find the item in the type enum
            return _typeFinder.TypeEnumContains(dataEnum.TypeEnum,value);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Set the current value of the LOV, by the value (a string value).
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SelectEnumStringVal(IDEnumString dataEnum, string value)
        {
            return SelectEnumVal(dataEnum, value);
        }

        //---------------------------------------------------------------------
        public ValueString SelectEnumValueStringAt(IDEnumString dataEnum, int pos)
        {
            return SelectEnumValueAt(dataEnum, pos) as ValueString;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Select a value in the LOV, by position.
        /// Set -1 to to have no selection. 
        /// </summary>
        /// <param name="dataLOV"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        public IValue SelectEnumValueAt(IDEnum dataLOV, int pos)
        {
            if (dataLOV == null)
                return null;
            // ok select this value
            return dataLOV.SelectValAt(pos);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Clear the selected values of the enum.
        /// </summary>
        /// <param name="lov"></param>
        /// <returns></returns>
        public int ClearEnumSelection(IDEnum dataEnum)
        {
            if (dataEnum == null)
                return 0;

            return dataEnum.ClearSelection();
        }

        #endregion

        //=====================================================================
        #region Public Create DataNamed Phy methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// create a var (dataNamed) typeof Physical Qty Length. 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="val"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public IDPhyLength CreateDPhyLength(string name, VarOrConst varOrConst, double val, TypePhyLengthPrefix prefix)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;

            // check if the type phy length is defined
            if (_typeMgr.TypePhyLength == null)
                return null;

            // first create a DVal phy length
            ValuePhyLength dval = _factoryMgr.FactoryValue.CreateValue(_typeMgr.TypePhyLength) as ValuePhyLength;

            // set the prefix
            dval.Prefix = prefix;
            // set the length value
            dval.Value = val;

            // create a data named
            IDPhyLength nd = new DPhyLength(name, _typeMgr.TypePhyLength, varOrConst, dval);

            // return the data named
            return nd;
        }


        //---------------------------------------------------------------------
        /// <summary>
        /// create a var (dataNamed) typeof Physical Qty Length. 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="val"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public IDPhyLength CreateVarPhyLength(string name, double val, TypePhyLengthPrefix prefix)
        {
            return CreateDPhyLength(name, VarOrConst.Var, val, prefix);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// create a const (dataNamed) typeof Physical Qty Length. 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="val"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public IDPhyLength CreateConstPhyLength(string name, double val, TypePhyLengthPrefix prefix)
        {
            return CreateDPhyLength(name, VarOrConst.Const, val, prefix);
        }
        //---------------------------------------------------------------------
        /// <summary>
        /// create a var (dataNamed) typeof Physical Qty Length. 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public IDPhyLength CreateVarPhyLength(string name)
        {
            return CreateVarPhyLength(name, 0, TypePhyLengthPrefix.Metre);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Set a value to a data named phys length.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="val"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public bool SetVal(IDPhyLength data, double val, TypePhyLengthPrefix prefix)
        {
            if (data == null)
                return false;

            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;
            data.DVal.Value = val;
            data.DVal.Prefix = prefix;
            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Set a value to a data named phys length.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="val"></param>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public bool SetVal(IDPhyLength data, double val)
        {
            if (data == null)
                return false;

            if (data.VarOrConst == VarOrConst.Const)
                // can't modify a constant
                return false;
            data.DVal.Value = val;
            return true;
        }

        #endregion

        //=====================================================================
        #region Public Create ListDataNamed methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create (and save) a new list to save data named.
        /// </summary>
        /// <param name="listName"></param>
        /// <returns></returns>
        public ListData CreateListData(string listName)
        {
            if (string.IsNullOrWhiteSpace(listName))
                return null;

            // check if the name is not already used by a list
            // TODO:

            // create the list and save it
            ListData listData = new ListData(listName);
            if (!_listDataMgr.Add(listData))
                return null;

            return listData;
        }

        #endregion

        //=====================================================================
        #region Private Create DataNamed (var & const) methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create a basic type data named (Var or Const).
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private IDBasic CreateDBasic(string name, ITypeBasic type, VarOrConst varOrConst)
        {
            IDBasic dBasic = _factoryMgr.FactoryData.CreateDBasic(name, type, varOrConst);

            return dBasic;
        }

        #endregion

        //=====================================================================
        #region Methods Methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Check the select mode, must match the select mode of the type
        /// </summary>
        /// <param name="typeEnum"></param>
        /// <param name="selectMode"></param>
        /// <returns></returns>
        private bool CheckEnumSelectMode(ITypeEnum typeEnum, DEnumSelectMode selectMode)
        {
            if(typeEnum==null)
                return false;

            if (typeEnum.SelectMode == TypeEnumSelectMode.SetInVar)
                return true;

            if (typeEnum.SelectMode == TypeEnumSelectMode.Single && selectMode== DEnumSelectMode.Single)
                return true;

            if (typeEnum.SelectMode == TypeEnumSelectMode.Many && selectMode == DEnumSelectMode.Many)
                return true;

            // err, mismatch
            return false;
        }
        #endregion


    }
}
